home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * objects.c
- *
- * This module implements the methods for objects and composite objects.
- *
- * from Persistence of Vision(tm) Ray Tracer
- * Copyright 1996 Persistence of Vision Team
- *---------------------------------------------------------------------------
- * NOTICE: This source code file is provided so that users may experiment
- * with enhancements to POV-Ray and to port the software to platforms other
- * than those supported by the POV-Ray Team. There are strict rules under
- * which you are permitted to use this file. The rules are in the file
- * named POVLEGAL.DOC which should be distributed with this file. If
- * POVLEGAL.DOC is not available or for more info please contact the POV-Ray
- * Team Coordinator by leaving a message in CompuServe's Graphics Developer's
- * Forum. The latest version of POV-Ray may be found there as well.
- *
- * This program is based on the popular DKB raytracer version 2.12.
- * DKBTrace was originally written by David K. Buck.
- * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
- *
- *****************************************************************************/
-
- #include "frame.h"
- #include "povray.h"
- #include "vector.h"
- #include "povproto.h"
- #include "objects.h"
- #include "texture.h"
- #include "halos.h"
-
-
-
- /*****************************************************************************
- * Local preprocessor defines
- ******************************************************************************/
-
-
-
- /*****************************************************************************
- * Local typedefs
- ******************************************************************************/
-
-
-
- /*****************************************************************************
- * Local variables
- ******************************************************************************/
-
- unsigned int Number_of_istacks;
- unsigned int Max_Intersections;
- ISTACK *free_istack;
-
-
-
- /*****************************************************************************
- * Static functions
- ******************************************************************************/
-
- static OBJECT *Copy_Bound_Clip PARAMS((OBJECT *Old));
- static void create_istack PARAMS((void));
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Intersection
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- int Intersection (Ray_Intersection, Object, Ray)
- INTERSECTION *Ray_Intersection;
- OBJECT *Object;
- RAY *Ray;
- {
- ISTACK *Depth_Stack;
- INTERSECTION *Local;
- DBL Closest = HUGE_VAL;
-
- if (Object == NULL)
- {
- return (FALSE);
- }
-
- if (!Ray_In_Bound (Ray,Object->Bound))
- {
- return (FALSE);
- }
-
- Depth_Stack = open_istack ();
-
- if (All_Intersections (Object, Ray, Depth_Stack))
- {
- while ((Local = pop_entry(Depth_Stack)) != NULL)
- {
- if (Local->Depth < Closest)
- {
- *Ray_Intersection = *Local;
-
- Closest = Local->Depth;
- }
- }
-
- close_istack (Depth_Stack);
-
- return (TRUE);
- }
- else
- {
- close_istack (Depth_Stack);
-
- return (FALSE);
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Inside_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- int Inside_Object (IPoint, Object)
- VECTOR IPoint;
- OBJECT *Object;
- {
- OBJECT *Sib;
-
- for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
- {
- if (!Inside_Object(IPoint, Sib))
- {
- return(FALSE);
- }
- }
-
- return (Inside(IPoint,Object));
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Ray_In_Bound
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- int Ray_In_Bound (Ray, Bounding_Object)
- RAY *Ray;
- OBJECT *Bounding_Object;
- {
- OBJECT *Bound;
- INTERSECTION Local;
-
- for (Bound = Bounding_Object; Bound != NULL; Bound = Bound->Sibling)
- {
- Increase_Counter(stats[Bounding_Region_Tests]);
-
- if (!Intersection (&Local, Bound, Ray))
- {
- if (!Inside_Object(Ray->Initial, Bound))
- {
- return (FALSE);
- }
- }
-
- Increase_Counter(stats[Bounding_Region_Tests_Succeeded]);
- }
-
- return (TRUE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Point_In_Clip
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- int Point_In_Clip (IPoint, Clip)
- VECTOR IPoint;
- OBJECT *Clip;
- {
- OBJECT *Local_Clip;
-
- for (Local_Clip = Clip; Local_Clip != NULL; Local_Clip = Local_Clip->Sibling)
- {
- Increase_Counter(stats[Clipping_Region_Tests]);
-
- if (!Inside_Object(IPoint, Local_Clip))
- {
- return (FALSE);
- }
-
- Increase_Counter(stats[Clipping_Region_Tests_Succeeded]);
- }
-
- return (TRUE);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Translate_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Translate_Object (Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- OBJECT *Sib;
-
- if (Object == NULL)
- {
- return;
- }
-
- for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
- {
- Translate_Object (Sib, Vector, Trans);
- }
-
- if (Object->Clip != Object->Bound)
- {
- for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
- {
- Translate_Object (Sib, Vector, Trans);
- }
- }
-
- Translate_Textures (Object->Texture, Trans);
-
- Translate_Halo_Container (Object->Texture, Trans);
-
- Translate (Object, Vector, Trans);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Rotate_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Rotate_Object (Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- OBJECT *Sib;
-
- if (Object == NULL)
- {
- return;
- }
-
- for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
- {
- Rotate_Object (Sib, Vector, Trans);
- }
-
- if (Object->Clip != Object->Bound)
- {
- for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
- {
- Rotate_Object (Sib, Vector, Trans);
- }
- }
-
- Rotate_Textures (Object->Texture, Trans);
-
- Rotate_Halo_Container (Object->Texture, Trans);
-
- Rotate (Object, Vector, Trans);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Scale_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Scale_Object (Object, Vector, Trans)
- OBJECT *Object;
- VECTOR Vector;
- TRANSFORM *Trans;
- {
- OBJECT *Sib;
-
- if (Object == NULL)
- {
- return;
- }
-
- for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
- {
- Scale_Object (Sib, Vector, Trans);
- }
-
- if (Object->Clip != Object->Bound)
- {
- for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
- {
- Scale_Object (Sib, Vector, Trans);
- }
- }
-
- Scale_Textures (Object->Texture, Trans);
-
- Scale_Halo_Container (Object->Texture, Trans);
-
- Scale (Object, Vector, Trans);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Transform_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Transform_Object (Object, Trans)
- OBJECT *Object;
- TRANSFORM *Trans;
- {
- OBJECT *Sib;
-
- if (Object == NULL)
- {
- return;
- }
-
- for (Sib = Object->Bound; Sib != NULL; Sib = Sib->Sibling)
- {
- Transform_Object (Sib, Trans);
- }
-
- if (Object->Clip != Object->Bound)
- {
- for (Sib = Object->Clip; Sib != NULL; Sib = Sib->Sibling)
- {
- Transform_Object (Sib, Trans);
- }
- }
-
- Transform_Textures (Object->Texture, Trans);
-
- Transform_Halo_Container (Object->Texture, Trans);
-
- Transform (Object,Trans);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Invert_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Invert_Object (Object)
- OBJECT *Object;
- {
- if (Object == NULL)
- {
- return;
- }
-
- Invert (Object);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Bound_Clip
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static OBJECT *Copy_Bound_Clip (Old)
- OBJECT *Old;
- {
- OBJECT *Current, *New, *Prev, *First;
-
- First = Prev = NULL;
-
- for (Current = Old; Current != NULL; Current = Current->Sibling)
- {
- New = Copy_Object (Current);
-
- if (First == NULL)
- {
- First = New;
- }
-
- if (Prev != NULL)
- {
- Prev->Sibling = New;
- }
-
- Prev = New;
- }
-
- return (First);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Copy_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- OBJECT *Copy_Object (Old)
- OBJECT *Old;
- {
- OBJECT *New;
-
- if (Old == NULL)
- {
- return (NULL);
- }
-
- New = Copy (Old);
- COOPERATE_0
-
- /*
- * The following copying of OBJECT_FIELDS is redundant if Copy
- * did *New = *Old but we cannot assume it did. It is safe for
- * Copy to do *New = *Old but it should not otherwise
- * touch OBJECT_FIELDS.
- */
-
- New->Methods = Old->Methods;
- New->Type = Old->Type;
- New->Sibling = Old->Sibling;
- New->Texture = Old->Texture;
- New->Bound = Old->Bound;
- New->Clip = Old->Clip;
- New->BBox = Old->BBox;
- New->Flags = Old->Flags;
-
- New->Sibling = NULL; /* Important */
-
- New->Texture = Copy_Textures (Old->Texture);
-
- New->Bound = Copy_Bound_Clip (Old->Bound);
-
- if (Old->Bound != Old->Clip)
- {
- New->Clip = Copy_Bound_Clip (Old->Clip);
- }
- else
- {
- New->Clip = New->Bound;
- }
-
- return (New);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_Object
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Destroy_Object (Object)
- OBJECT *Object;
- {
- OBJECT *Sib;
-
- while (Object != NULL)
- {
- Destroy_Textures (Object->Texture);
-
- Destroy_Object (Object->Bound);
-
- if (Object->Bound != Object->Clip)
- {
- Destroy_Object (Object->Clip);
- }
-
- Sib = Object->Sibling;
-
- Destroy(Object);
-
- Object = Sib;
- }
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * create_istack
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- static void create_istack()
- {
- ISTACK *New;
-
- New = (ISTACK *)POV_MALLOC(sizeof (ISTACK), "istack");
-
- New->next = free_istack;
-
- free_istack = New;
-
- New->istack = (INTERSECTION *)POV_MALLOC(Max_Intersections * sizeof (INTERSECTION), "istack entries");
-
- Number_of_istacks++;
- }
-
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * Destroy_IStacks
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void Destroy_IStacks()
- {
- ISTACK *istk, *temp;
-
- istk = free_istack;
-
- while (istk != NULL)
- {
- temp = istk;
-
- istk = istk->next;
-
- POV_FREE (temp->istack);
-
- POV_FREE (temp);
- }
-
- free_istack = NULL;
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * open_sstack
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- ISTACK *open_istack()
- {
- ISTACK *istk;
-
- if (free_istack == NULL)
- {
- create_istack ();
- }
-
- istk = free_istack;
-
- free_istack = istk->next;
-
- istk->top_entry = 0;
-
- return (istk);
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * close_istack
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void close_istack (istk)
- ISTACK *istk;
- {
- istk->next = free_istack;
-
- free_istack = istk;
- }
-
-
-
- /*****************************************************************************
- *
- * FUNCTION
- *
- * incstack
- *
- * INPUT
- *
- * OUTPUT
- *
- * RETURNS
- *
- * AUTHOR
- *
- * POV-Ray Team
- *
- * DESCRIPTION
- *
- * -
- *
- * CHANGES
- *
- * -
- *
- ******************************************************************************/
-
- void incstack(istk)
- ISTACK *istk;
- {
- if (++istk->top_entry >= Max_Intersections)
- {
- istk->top_entry--;
-
- Increase_Counter(stats[Istack_overflows]);
- }
- }
-